﻿#region Legal

// Jimmy Zimmerman
// Team Mongoose
//
// END USER LICENSE AGREEMENT
// IMPORTANT - READ THIS CAREFULLY:  This End User License Agreement is a legal agreement
// between you (either an individual, business entity, currently active identity of an
// individual with Multiple Personality Disorder, octopus overlord, or otherworldly entity),
// and Team Mongoose, for the enclosed, components.
//
// By reading this document and/or installing this product, you agree to be bound by the
// terms of this EULA.
//
// Team Mongoose owns all copyright, trade secret, trademark, trade wars,
// patent, portent, and potential rights to these components.  Team Mongoose
// grants you the right to deploy the enclosed components.
//
// If you agree to the terms of this EULA, a license to use these components is granted to you.
//
// If you should happen to benefit from the enclosed components, then you are legally and
// contractually bound to thank us for it. Send your regards to jimmyzimms@hotmail.com.
//
// OTHER RIGHTS AND LIMITATONS
// You may not reverse-engineer, decompile, decode, disassemble, psycho-analyze, or otherwise
// attempt to find hidden meanings between the lines of this EULA; unless, of course, you should
// happen to find some, and they are funny.
//
// You may not translate this EULA or any part of the components into Ancient Sumerian.
//
// THESE COMPONENTS ARE PROVIDED “AS-IS” WITHOUT WARRANTY OF ANY KIND. ANY USE OF THE COMPONENTS
// CONTAINED IS AT YOUR OWN RISK. TEAM MONGOOSE DISCLAIM ALL WARRANTIES, EITHER
// EXPRESS OR IMPLIED, WITH RESPECT TO THE ACCURRACY AND CORRECTNESS OF THE COMPONENTS CONTAINED
// HEREIN. TEAM MONGOOSE DOES NOT WARRANT THAT THE COMPONENTS ARE FLAWLESS.
//
// REDISTRIBUTION AND USE IN SOURCE AND BINARY FORMS, WITH OR WITHOUT MODIFICATION, ARE PERMITTED
// PROVIDED THAT THE FOLLOWING CONDITIONS ARE MET:
// * REDISTRIBUTIONS OF SOURCE CODE MUST RETAIN THE ABOVE COPYRIGHT NOTICE
// * REDISTRIBUTIONS IN BINARY FORM MUST NOTE THE USE OF THE COMPONENT IN DOCUMENTATION AND/OR
//   OTHER MATERIALS PROVIDED WITH THE DISTRIBUTION.
// * NEITHER THE NAME OF TEAM MONGOOSE MAY BE USED TO ENDORES OR PROMOTE PRODUCTS
//   DERIVED FROM THIS SOFTWARE WITHOUT SPECIFIC PRIOR WRITTEN PERMISSION.
//
// IN NO EVENT SHALL TEAM MONGOOSE BE HELD LIABLE FOR INCIDENTAL, SPECIAL, INDIRECT,
// INCONSEQUENTIAL, UNBELIEVABLE, EXAGGERATED, VERBOSE, OR TYPICAL DAMAGES INCURRED WHILE USING
// THE ENCLOSED COMPONENTS.
//
// OUR STUFF ALWAYS WORKS - SOMETIMES.

#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Mongoose.Games.BfgRoster.Tests
{
    [TestClass()]
    public class OrdinanceBayTests
    {
        [TestMethod()]
        public void ConstructorShouldRequireWeapon()
        {
            try
            {
                new OrdinanceBay(Bearing.Bow, null);

                Assert.Fail("Exception should have been thrown");
            }
            catch (ArgumentNullException exception)
            {
                Assert.AreEqual("Value cannot be null.\r\nParameter name: weapon", exception.Message);
            }
        }

        [TestMethod()]
        public void ConstructorShouldSetExpectedValues()
        {
            var ordinance = new Ordinance("Name", 1, 1);
            var bay = new OrdinanceBay(Bearing.Dorsal, ordinance);

            Assert.AreEqual(ordinance.DeploymentsCapable, bay.DeploymentsAvailable);
            Assert.AreEqual(Bearing.Dorsal, bay.FireArc);
            Assert.IsFalse(bay.IsDeployed);
            Assert.AreSame(bay.Weapon, ordinance);
        }

        [TestMethod()]
        public void DeployShouldSetValues()
        {
            var ordinance = new Ordinance("Name", 1, 1);
            var bay = new OrdinanceBay(Bearing.Dorsal, ordinance);
   
            bay.Deploy(1);
            Assert.IsTrue(bay.IsDeployed);
            Assert.AreEqual(0, bay.DeploymentsAvailable);
        }

        [TestMethod()]
        public void DeployShouldRaiseEventsWhenAvailableExpended()
        {
            List<PropertyChangedEventArgs> raisedArgs = new List<PropertyChangedEventArgs>();

            var ordinance = new Ordinance("Name", 1, 1);
            var bay = new OrdinanceBay(Bearing.Dorsal, ordinance);
            bay.PropertyChanged += (source, args) => raisedArgs.Add(args);
            bay.Deploy(1);

            Assert.IsNotNull(raisedArgs);
            Assert.AreEqual(2, raisedArgs.Count);
            Assert.AreEqual("DeploymentsAvailable", raisedArgs[0].PropertyName);
            Assert.AreEqual("IsDeployed", raisedArgs[1].PropertyName);
        }

        [TestMethod()]
        public void DeployShouldRaiseEventWhenAvailableNotExpended()
        {
            List<PropertyChangedEventArgs> raisedArgs = new List<PropertyChangedEventArgs>();

            var ordinance = new Ordinance("Name", 1, 2);
            var bay = new OrdinanceBay(Bearing.Dorsal, ordinance);
            bay.PropertyChanged += (source, args) => raisedArgs.Add(args);
            bay.Deploy(1);

            Assert.IsNotNull(raisedArgs);
            Assert.AreEqual(1, raisedArgs.Count);
            Assert.AreEqual("DeploymentsAvailable", raisedArgs[0].PropertyName);
            Assert.IsFalse(bay.IsDeployed);
        }

        [TestMethod()]
        public void DeployShouldRequireAtLeast1()
        {
            var ordinance = new Ordinance("Name", 1, 1);
            var bay = new OrdinanceBay(Bearing.Dorsal, ordinance);

            try
            {
                bay.Deploy(0);
                Assert.Fail("Exception should have been thrown");
            }
            catch (ArgumentOutOfRangeException exception)
            {
                Assert.AreEqual("The number of ordinance weapon instances to deploy is less than 1. Actual value '0'.\r\nParameter name: instancesToDeploy", exception.Message);
            }
        }

        [TestMethod()]
        public void DeployShouldCannotExccedAvailable()
        {
            var ordinance = new Ordinance("Name", 1, 1);
            var bay = new OrdinanceBay(Bearing.Dorsal, ordinance);

            try
            {
                bay.Deploy(2);
                Assert.Fail("Exception should have been thrown");
            }
            catch (InvalidOperationException exception)
            {
                Assert.AreEqual("The number of ordinance weapon instances to deploy '2' is greater than the remaining number of deployments remaining '1'", exception.Message);
            }
        }
    }
}
